Computer software is often complex. Part of the complexity may arise from the nature of the work a program is designed to perform, e.g., tracking large numbers of real world items or ongoing transactions over hours or longer periods of time, coordinating activities with other complex software, controlling complex hardware, and so on. In almost any real-world use of software, complexity also arises because many details are introduced and should be correctly managed in order to instruct computer hardware how to perform real-world work that is initially described much less precisely in English or another natural language. That is, the transformation from a high-level description to a low-level implementation which is executable by a computer system, inevitably introduces complexity. Even programming language source code, which is more precise than natural languages, is still at a relatively high level and therefore is ambiguous, being open to various understandings and implementations. Source code is transformed into low-level instructions that can be directly executed by computational hardware, with many details being introduced and choices being made during that transformation.
Complexity introduces the all-too-often realized possibility of programming errors, a.k.a. “bugs”. The process of identifying the cause of a bug and attempting to modify a program to remediate or remove the bug's impact is referred to as “debugging”. Specialized software tools which assist debugging are called “debuggers”. The program being debugged is called the “debuggee”.
Debugging is perhaps easiest when a developer can run the debuggee slowly, or at full speed, or pause execution of the debuggee, all at will, and can examine all state information of the debuggee at any point in the debuggee's execution. This is known as “live process debugging”. However, such full access to a debuggee is often not available. For example, the debuggee may be production software that cannot be debugged live without violating service agreements or harming the reputation, security, or finances of an interested party. Unacceptable harms may occur if the live process debuggee is paused for seconds at a time while the developer examines variable values, checks to see which functions were called with which parameter values, reviews the source code, considers possible explanations for the bug, and devises tests that might help identify, remediate, or eliminate the bug.
Accordingly, sometimes state information is recorded as the debuggee executes, to be examined later without substantially pausing the debuggee's execution. Creating such a recording may slow down the debuggee, but the recording may provide helpful information without hurting production performance targets the way live debugging could. For instance, the debuggee may be paused just long enough to create a memory dump which copies to disk some or all of the memory values pertinent to the debugger at a particular point in time. Some aspects of the debuggee's execution may also be recorded in an execution trace. Some debuggers support use of such a trace to replay the execution of the traced debuggee, without the debuggee being a live process. With some debuggers, the debuggee execution can be replayed in forward or in reverse, thus permitting “time travel”, “reverse”, or “historic” debugging.
However, because an execution trace may contain less information than is sometimes available during live process debugging, and because the execution trace records state information at a low level, technical challenges arise when a debugger or other software tool attempts to control replay execution, namely, execution that is based on the recorded trace. Depending on the implementation, execution control operations that are familiar to developers and are often used during live debugging may be less accurate when attempted during a trace-based replay, or may not be available at all.
Accordingly, advances in efficiently and accurately implementing high-level execution control using a low-level execution trace could help improve the information that is available to developers or to automated performance monitoring tools, through a debugger or another replay or logging tool. Thus, such advances will tend to improve the function of computer systems by facilitating an accurate understanding of computer system behavior, and by promoting the mitigation or eradication of computer system bugs.